<template>
  <page-meta :root-font-size="rootFontSize() + 'px'"> </page-meta>

  <view class="page-container" v-show="delayShow">
    <customHeader isShowProcess :progress="progress" :title="headerTitle" />

    <view class="words-container" :style="{ top: height }">
      <view class="words-wrapper">
        <words v-if="isPreview" :preview="preview[curIndex]" />
        <sentence v-else :dialogue="dialogue[curIndex]" />
      </view>
      <view class="record-operate">
        <speakingSound :voice="userVoice" :prevIcon="prevIcon" :nextIcon="nextIcon" @prev="handleToPrev"
          @next="handleToNext" @on-upload-success="handleRecorderSuccess">
          <template #operate-content>
            <view v-if="isShowTransition">
              <image :class="[transitionShow ? 'cheese-reward' : 'leave-active']"
                src="https://rwstatic.tentons.cn/web/Lesson/images/100-cheese-icon.png" />
            </view>
          </template>
        </speakingSound>
      </view>
    </view>
  </view>

  <CwCommon />
</template>

<script setup lang="ts">
import { ref, computed, onBeforeUnmount, nextTick } from 'vue';
import { rootFontSize, util } from "@/utils/util";
import words from "./words.vue";
import sentence from "./sentence.vue";
import customHeader from "@/components/customHeader.vue";
import speakingSound from "@/components/speakingSound.vue";
import { onLoad, onHide } from "@dcloudio/uni-app";
import API from "@/api";
import type { IUploadSuccessInfo } from "@/components/recordSound.vue";
import type { IPreview, IDialogue, IDialogueLesson } from "@/pages/lowPricedCourse/dialogueOriginText/index";
import { startEvaluating } from "@/utils/chivox";
import { useDelayShow } from "@/hooks/useDelayShow";

const { delayShow } = useDelayShow();

const speakingPrev = "https://rwstatic.tentons.cn/web/Lesson/images/speaking-prev.png";
const speakingPrevActive = "https://rwstatic.tentons.cn/web/Lesson/images/speaking-prev-active.png";
const speakingNext = "https://rwstatic.tentons.cn/web/Lesson/images/speaking-next.png";
const speakingNextActive = "https://rwstatic.tentons.cn/web/Lesson/images/speaking-next-active.png";

const fs = uni.getFileSystemManager();
const height = ref(getApp().globalData!.pageProcessTop);

const isPreview = ref(true);
const isRelearn = ref(false); // 判断是否是重学
const courseStep = ref(0);
const curIndex = ref(0);
const stepWidth = ref(0);
const progress = ref(0);
const userVoice = ref("");
const sectionId = ref("");
const preview = ref<IPreview[]>([]);
const dialogue = ref<IDialogue[]>([]);
const previewMap = ref<Map<any, any>>(new Map());
const dialogueMap = ref<Map<any, any>>(new Map());
const studyTime = ref(0);
const headerTitle = ref("");
const isShowTransition = ref(false);

let timer: number | undefined;

onLoad(async (option: any) => {
  sectionId.value = option.section_id;
  courseStep.value = Number(option.courseStep);

  if (option.data) {
    const result: IDialogueLesson = JSON.parse(decodeURIComponent(option.data));

    isRelearn.value = result.isRelearn;
    isPreview.value = result.data.isPreview;
    preview.value = result.data.questions.preview;
    dialogue.value = result.data.questions.dialogue;
    curIndex.value = result.data.currentQuestionIndex;
  }

  timer = setInterval(() => {
    studyTime.value += 1;
  }, 1000);

  if (isPreview.value) {
    handleSetPreview();
  } else {
    handleSetDialogue();
  }

  getCurUserVoice();

  isShowTransition.value = false;
  await nextTick();
  setTimeout(() => {
    if (transitionShow.value) {
      isShowTransition.value = true;
    }
  }, 10);
});

const transitionShow = computed(() => {
  return !isPreview.value && dialogue.value[curIndex.value].is_reward == 0;
})

const prevIcon = computed(() => {
  return curIndex.value > 0 ? speakingPrevActive : speakingPrev;
})

const nextIcon = computed(() => {
  const maxLength = isPreview.value ? preview.value.length - 1 : dialogue.value.length - 1;
  return curIndex.value <= maxLength ? speakingNextActive : speakingNext;
})

const currentQuestion = computed<IPreview | IDialogue>(() => {
  if (isPreview.value) {
    const temp = preview.value[curIndex.value];
    return previewMap.value.get(temp.preview_id);
  } else {
    const temp = dialogue.value[curIndex.value];
    return dialogueMap.value.get(temp.dialogue_txt_id);
  }
})

const handleSetDialogue = () => {
  headerTitle.value = "对话原文";
  isPreview.value = false;
  dialogue.value.forEach((item: IDialogue) => {
    dialogueMap.value.set(item.dialogue_txt_id, item);
  });

  stepWidth.value = 100 / dialogue.value.length;
  progress.value = stepWidth.value * curIndex.value;
};

const handleSetPreview = () => {
  headerTitle.value = "单词预习";
  isPreview.value = true;
  preview.value.forEach((item: IPreview) => {
    previewMap.value.set(item.preview_id, item);
  });

  stepWidth.value = 100 / preview.value.length;
  progress.value = stepWidth.value * curIndex.value;
};

const getCurUserVoice = () => {
  userVoice.value = currentQuestion.value.user_voice;
};

const handleFirstReport = async () => {
  if (isPreview.value) {
    const item = currentQuestion.value as IPreview;
    previewMap.value.set(item.preview_id, Object.assign(item, {
      is_comp: 1,
    }));
    const previewVal = previewMap.value.get(item.preview_id);

    const params = {
      section_id: sectionId.value,
      preview: [previewVal],
    };

    await API.previewReport(params);
  } else {
    const item = currentQuestion.value as IDialogue;
    dialogueMap.value.set(item.dialogue_txt_id, Object.assign(item, {
      is_comp: 1,
    }));
    const dialogueVal = dialogueMap.value.get(item.dialogue_txt_id);

    const params = {
      section_id: sectionId.value,
      dialogue: [dialogueVal],
    };

    await API.dialogueTxtReport(params);
  }
}

const handleReportParams = async () => {
  util.showLoading();

  if (isPreview.value) {
    const params = {
      section_id: sectionId.value,
      preview: Array.from(previewMap.value.values()),
    };
    await API.previewReport(params);
  } else {
    const params = {
      section_id: sectionId.value,
      dialogue: Array.from(dialogueMap.value.values()),
    };
    await API.dialogueTxtReport(params);
  }

  util.hideLoading();
};

const handleToPrev = async () => {
  if (curIndex.value > 0) {
    curIndex.value -= 1;
    progress.value = Math.max(0, progress.value - stepWidth.value);

    isShowTransition.value = false;
    await nextTick();
    setTimeout(() => {
      if (transitionShow.value) {
        isShowTransition.value = true;
      }
    }, 100);

    getCurUserVoice();
  } else {
    console.log("prev", curIndex.value);
  }
};

const handleToNext = async () => {
  // 新学上报
  if (!isRelearn.value) {
    util.showLoading();
    await handleFirstReport();
    util.hideLoading();
  }

  const maxLength = isPreview.value ? preview.value.length - 1 : dialogue.value.length - 1;

  if (curIndex.value < maxLength) {
    curIndex.value += 1;
    progress.value += stepWidth.value;

    isShowTransition.value = false;
    await nextTick();
    setTimeout(() => {
      if (transitionShow.value) {
        isShowTransition.value = true;
      }
    }, 100);

    getCurUserVoice();
  } else {
    if (isRelearn.value) {
      await handleReportParams();
    }
    if (isPreview.value) {
      curIndex.value = 0;
      handleSetDialogue();
    } else {
      uni.redirectTo({
        url: `/pages/lowPricedCourse/trialCourseHome/transitionPage/index?lastCourseStep=${courseStep.value}&courseStep=${courseStep.value + 1}&section_id=${sectionId.value}`,
      });
    }
  }
};

const handleTimeLongReport = async () => {
  await API.timeLongReport({
    section_id: sectionId.value,
    is_first: isRelearn.value ? 0 : 1,
    time_long: studyTime.value,
  });
};

const handleRecorderSuccess = (info: IUploadSuccessInfo) => {
  util.showLoading();

  userVoice.value = info.ossFilePath;
  let tempItem: IPreview & IDialogue;
  let sentence = "";

  if (isPreview.value) {
    // @ts-ignore
    tempItem = preview.value[curIndex.value];
    sentence = tempItem.word;
    preview.value[curIndex.value].user_voice = userVoice.value;
  } else {
    // @ts-ignore
    tempItem = dialogue.value[curIndex.value];
    sentence = tempItem.sentences;
    dialogue.value[curIndex.value].user_voice = userVoice.value;
  }

  fs.readFile({
    filePath: info.localFilePath,
    success: (res) => {
      startEvaluating({
        evaluatingInfo: { sentence: sentence },
        audioBuffer: res.data as ArrayBuffer,
        onSuccess: async (val) => {
          // 未获取奖励上报
          if (dialogue.value[curIndex.value].is_reward == 0) {
            dialogue.value[curIndex.value].is_reward = 1;

            await handleFirstReport();
            if (transitionShow.value) {
              const innerAudioContext = uni.createInnerAudioContext();
              innerAudioContext.autoplay = true;
              innerAudioContext.src = "https://recite-words.oss-cn-hangzhou.aliyuncs.com/web/Lesson/audio/SKU_get_cheese.mp3";
            }
          }

          if (isPreview.value) {
            previewMap.value.set(tempItem.preview_id, Object.assign(currentQuestion.value, {
              is_comp: 1,
              user_voice: userVoice.value,
              preview_id: tempItem.preview_id,
              analysis: JSON.stringify(val),
            }));
          } else {
            dialogueMap.value.set(tempItem.dialogue_txt_id, Object.assign(currentQuestion.value, {
              is_comp: 1,
              is_reward: 1,
              user_voice: userVoice.value,
              analysis: JSON.stringify(val),
              dialogue_txt_id: tempItem.dialogue_txt_id,
            }));
          }

          setTimeout(() => {
            util.hideLoading();
          }, 300);
        },
        onError: (errMsg) => {
          util.hideLoading();
          util.showDialogue(errMsg);
        },
      });
    },
    fail: () => {
      util.hideLoading();
      util.showDialogue("找不到音频文件");
    },
  });
};

onBeforeUnmount(async () => {
  clearInterval(timer);
  await handleTimeLongReport();

  studyTime.value = 0;
});
</script>

<style scoped lang="scss">
.page-container {
  width: 100vw;
  height: 100vh;
  background-color: $uni-bg-color-minor;

  .words-container {
    position: absolute;
    width: 37.5rem;
    top: 10rem;
    bottom: 0;
    left: 50%;
    transform: translateX(-50%);
    background: $uni-bg-color-minor;

    .words-wrapper {
      width: 100%;
      height: calc(100% - 3.8rem);
      overflow-x: hidden;
      overflow-y: auto;
    }

    .record-operate {
      position: absolute;
      bottom: 5.5rem;
      left: 0;
      right: 0;
      height: 6rem;

      .cheese-reward {
        position: absolute;
        top: -3.5rem;
        right: 5.5rem;
        width: 7.2rem;
        height: 2.9rem;
      }

      .leave-active {
        position: absolute;
        top: -3.5rem;
        right: 5.5rem;
        width: 7.2rem;
        height: 2.9rem;
        opacity: 0;
        animation: hide .3s forwards;
      }

      @keyframes hide {
        from {
          opacity: 1;
          transform: translateY(0);
        }

        to {
          opacity: 0;
          transform: translateY(-3rem);
        }
      }
    }
  }
}
</style>